#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# Author: Jiachen Fan
# Create: 2021-3-19
# ******************************************************************************/
"""
Find the differences between
the contents of the files and save them
"""
import os
import logging
from src.util.dnf_utils import dnf_info_src

# use dnf list to generate the list of pkgs
OE_PKGS_PATH = "all_pkgs"
OBS_PKGS_PATH = "all_obs_pkgs"
OUTPUT_FILE = "diff_pkgs.csv"
NOT_FIND_FILE = "not_find_pkgs.csv"

WORK_DIR = os.path.dirname(os.path.abspath(__file__))

logging.getLogger().setLevel(logging.INFO)


def change_bin2src(file_path):
    """
    change bin src
    Args:
        file_path: file path

    Returns:
        result_dict: The contents of the file
    """
    result_dict = dict()
    if not os.path.isfile(file_path):
        logging.error("file not exist")
        return result_dict
    with open(file_path, "r") as bin_file:
        for line in bin_file:
            data = line.split()
            suffix_len = len(data[0].split(".")[-1]) + 1
            name = data[0][:-1 * suffix_len]
            v = data[1]
            if not result_dict.has_key(name):
                result_dict[name] = v
            else:
                if v > result_dict[name]:
                    result_dict[name] = v
    return result_dict


def get_source_name(bin_name, repo=""):
    """
    get source package name
    Args:
        bin_name: bin package name
        repo: repo

    Returns:
        src name: src package name
    """
    data, code = dnf_info_src(bin_name, repo)
    info = data.split("\n")[0]
    if "No matching" in info:
        return None
    src_name = info.split(":")[-1].strip().rsplit("-", 2)[0]
    logging.info("get src name bin: %s, src: %s", bin_name, src_name)
    return src_name


def change_all_bin2src(bin_set, src_map):
    """
    Change all binary to source
    Args:
        bin_set: bin package set
        src_map: src package map

    Returns:
        src_set: src package set
    """
    src_set = set()
    for bin_name in bin_set:
        src_name = get_source_name(bin_name)
        if src_name and not src_name in src_map:
            src_set.add(src_name)
    return src_set


def find_diff(d1, d2):
    """
    Find the difference
    Args:
        d1: The data dictionary
        d2: The data dictionary

    Returns:
        result_set: result set
        not_find_list: not found list
    """
    temp_list = list()
    not_find_list = list()
    result_set = set()
    for k, v in d1.items():
        if v != d2.get(k, ""):
            if d2.has_key(k):
                temp_list.append([k, v, d2.get(k, "not found")])
            else:
                not_find_list.append([k, v, d2.get(k, "not found")])
    for element in temp_list:
        element[0] = get_source_name(element[0])
        if element[0] not in result_set:
            result_set.add(element[0])

    return list(result_set), not_find_list


def save_diff(l, path):
    """
    Save the data to a file
    Args:
        l: l
        path: file path

    Returns:

    """
    with open(path, "w+") as f:
        for element in l:
            f.write(element[0] + ", " + element[1] + ", " + element[2] + "\n")


if __name__ == "__main__":
    oe_dict = change_bin2src(OE_PKGS_PATH)
    obs_dict = change_bin2src(OBS_PKGS_PATH)
    diff_list, not_find_list = find_diff(oe_dict, obs_dict)
    save_diff(diff_list, OUTPUT_FILE)
    save_diff(not_find_list, NOT_FIND_FILE)
